#pragma once

#ifdef MXPLUGINMANAGER_EXPORTS
#define MXPLUGINMANAGER_API __declspec(dllexport)
#else
#define MXPLUGINMANAGER_API __declspec(dllimport)
#endif

#pragma warning(suppress: 4995)
#include <vector>

#include "MxPluginLib.h"
#include "gLibDetails.h"

class MXPLUGINMANAGER_API MxPluginManager 
{
public:
	static const char * const MxPluginManager::FnNameCreateClassInstance;
	static const char * const MxPluginManager::ErrorCodeList;
	static const wchar_t * const MxPluginManager::wErrorCodeList;

	static const DWORD MxPluginManager::NoError = 0;						//GetLastError() returns values in range 0 (success) to 15999
	static const DWORD MxPluginManager::UnknownError = 30000;		
	static const DWORD MxPluginManager::CreateMxPluginLibError = 30001;
	static const DWORD MxPluginManager::AddMxPluginLibError = 30002;
	static const DWORD MxPluginManager::ExceptionError = 30003;
	static const DWORD MxPluginManager::InvalidParams = 3004;
	static const DWORD MxPluginManager::NoMxPluginsForIDD = 30005;
	static const DWORD MxPluginManager::InvalidRegKey = 30006;

public:
	MxPluginManager(void);
	~MxPluginManager(void);

	void			ClearAllMxPlugins();

	int				GetPluginCount() { return static_cast<int>(_Libs.size()); } 
	MxPluginLib *	GetPlugin(int index) { return ((index >= 0) && (index < (int)_Libs.size())) ? _Libs[index] : '\0'; }
	MxPluginLib *	GetPlugin(const char *LibID);
	DWORD			RefreshPluginsInSubFolders(const wchar_t *PluginRootFolder, const char *IID);
	DWORD			RefreshPluginsInFolder(const wchar_t *PluginFolder, const char *IID);

	const char *GetLibName(void) { return ::gLibName();	}							//VS_VERSION_INFO::ProductName
	const char *GetLibDescription(void) { return ::gLibDescription(); }				//VS_VERSION_INFO::FileDescription
	const char *GetLibVersion(void) { return ::gLibVersion(); }						//VS_VERSION_INFO::ProductVersion
	const char *GetLibOwnerName(void) { return ::gLibOwnerName();	}				//VS_VERSION_INFO::CompanyName
	const char *GetLibCopyrightNotice(void) { return ::gLibCopyrightNotice(); }		//VS_VERSION_INFO::LegalCopyright
	const char *GetLibInternalName() { return ::gLibID(); }							//VS_VERSION_INFO::Internal Name

	const char *GetLibSupportSite(void) { return "http://www.mxplugin.org";	}		
	const char *GetLibLicenseName(void) { return "New BSD Licence"; }								
	const char *GetLibLicenseURL(void)  { return "http://mxplugin.codeplex.com/license"; }	
	const wchar_t *GetLibPathFilename(void) { return ::gLibPathFilename(); }		//filename returned by ::GetModuleFileName() of hModule in DllMain, DLL_PROCESS_ATTACH	



private:
	DWORD		RefreshPlugins(const wchar_t *PluginFolder, const char *IID);
	bool		AddMxPlugin(MxPluginLib *lib);	
	bool		IsExisting(MxPluginLib *lib);
	void		ClearAllSelections();
	bool		DeleteNextUnselected();


	DWORD		GetFirstPluginFolderItem(std::wstring *firstFolderResult, const wchar_t *PluginRootFolder, HANDLE *hFindFolder, bool FindFolder);
	DWORD		GetNextPluginFolderItem(std::wstring *nextFolderResult, const wchar_t *PluginFolder, HANDLE *hFindFolder, bool FindFolder);
	bool		IsValidLib(const wchar_t *filename);

private:
#pragma warning(suppress: 4251)
	std::vector<MxPluginLib *> _Libs;

};